package org.javaopenaccess.dao;

import org.aopalliance.intercept.MethodInvocation;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectServer;

public class Db4oTransactionManager extends AbstractDb4oTransactionManager implements TransactionManager{

	private ObjectServer server;
	/**
	 * This constructor starts the transactionmanager in Server mode.
	 * Also starts the Db4o Server service.
	 * @param path
	 * @param name
	 * @param port
	 */
	public Db4oTransactionManager(String path, String name, int port) {
		super();
		//FIXME: THis should be pooled somehow?
		//Also, This should be opened with a configuration object (see db4o api Configuration)
		//Also, this starts the db server, so maybe it's should have it's own class for starting and closing
		server = Db4o.openServer(path + "/" + name, port);	
	}
	
	public ObjectContainer startTransaction(AbstractSupportDao dao){
		AbstractDb4oSupportDao db4oDao = (AbstractDb4oSupportDao) dao;
		logger.info("Opening db4o container for schema");
		ObjectContainer container = server.openClient();
		db4oDao.setSession(container);
		logger.debug("db4o session started");
		return container;
	}

	@Override
	public Object interceptedTransaction(MethodInvocation invocation) throws Throwable {
		ObjectContainer con = startTransaction((AbstractSupportDao) invocation.getThis());
		try {
			Object result = invocation.proceed();
			stopTransaction(con, true);
			return result;
		} catch (Throwable e) {
			logger.info("error occurred in the invocation. Re-throwing and rolling back the transaction");
			e.printStackTrace();
			stopTransaction(con, false);
			throw e;
		}
	}
}
